﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using SoccerScore.Compact.Linq.Review;
using SoccerScore.Compact.Linq;
using DevExpress.XtraCharts;
using System.Reflection;

namespace Soccer_Score_Forecast
{
    public class PredictAnalysisAfter
    {
        private DataClassesMatchDataContext2 matches = new DataClassesMatchDataContext2(Conn.conn);
        public IEnumerable<Analysis_Review> GetPredictTwo_Today(int overday)
        {
            var tables = matches.Analysis_Review
                        .Where(e => e.Match_time.Value > DateTime.Now.AddDays(overday))
                //.Where(e => e.Result_goals.Length == 3)  //只有2个结果，修改成3个结果的
                  //.Where(e => e.Data_wdl.Length != 3) //不等于3
                        .Where(e => e.bj_select == 2)  //非让球的
                        .OrderBy(e => e.Match_time);
            return tables.AsEnumerable();
        }
        public IEnumerable<Analysis_Review> GetPredictTwo_TodayFilter(int overday, List<string> filter_match_two)
        {
            //getBjDangChang();
            //DataClassesMatchDataContext2 matches = new DataClassesMatchDataContext2(Conn.conn);
            var tables = matches.Analysis_Review
                               .Where(e => e.Match_time.Value > DateTime.Now.AddDays(overday))
                                .Where(e => filter_match_two.Contains(e.Match_type))  //上次赢了的类型
                //.Where(e => bjdanchang.Contains(e.Match_type)) //出错率大于50的类型
                //.Where(e=>e.Result_goals=="30") 
                 //.Where(e => e.Data_wdl.Length != 3) //不等于3
                               .Where(e => e.bj_select == 2)
                               .OrderBy(e => e.Match_time);
            return tables.AsEnumerable();
        }
        public IEnumerable<Analysis_Review> GetPredictTwo()
        {
            var ar = from p in matches.Analysis_Review.Where(p => p.Result_wdl != null).AsParallel()
                     where p.bj_select == 2
                     //where p.result_grnn != null

                     //where todayMatchType_two.Contains(p.Match_type)
                     where p.result_grnn.Contains("yes") || p.result_grnn.Contains("no")
                     //where p.Result_wdl.Contains("W") || p.Result_wdl.Contains("L")
                     //where p.Result_wdl != null
                     //where p.Result_goals =="30"
                     //where p.Result_goals.Length != 3
                     //where p.Data_wdl.Length != 3
                     select p;
            return ar.AsEnumerable();
        }
        public IEnumerable<Analysis_Review> GetPredictTwo_Match(string tt)
        {
            var ar = from p in matches.Analysis_Review.Where(p => p.Result_wdl != null).AsParallel()
                     where p.bj_select == 2
                     //where p.result_grnn != null
                     where p.Match_type == tt
                     //where todayMatchType_two.Contains(p.Match_type)
                     where p.result_grnn.Contains("yes") || p.result_grnn.Contains("no")
                     //where p.Result_wdl.Contains("W") || p.Result_wdl.Contains("L")
                     //where p.Result_wdl != null
                     //where p.Result_goals =="30"
                     //where p.Result_goals.Length != 3
                     //where p.Data_wdl.Length != 3
                     orderby p.Match_time
                     select p;
            return ar.AsEnumerable();

        }
        public List<string> GetTodayMatch()
        {
            var artype = matches.Analysis_Review.AsParallel()
                //.Where(e => e.result_grnn == null)
                //.Where(e => e.Result_wdl == null
                //.Where(e=>!e.Result_wdl.Contains("W") && !!e.Result_wdl.Contains("L"))
                    .Where(e => e.full_home_goals == null)
                    .Select(e => e.Match_type).Distinct();
            return artype.ToList();
        }
        public IEnumerable<Analysis_Review> GetPredictOne_Today(int overday)
        {
            var tables = matches.Analysis_Review
      .Where(e => e.Match_time.Value > DateTime.Now.AddDays(overday))
                //.Where(e => e.Result_goals.Length == 3)  //只有2个结果，修改成3个结果的
    .Where(e => e.bj_select == 1)  //非让球的
    .OrderBy(e => e.Match_time);
            return tables;

        }
        public IEnumerable<Analysis_Review> GetPredictOne_TodayFilter(int overday, List<string> filter_match)
        {
            var tables = matches.Analysis_Review
                    .Where(e => e.Match_time.Value > DateTime.Now.AddDays(overday))
                     .Where(e => filter_match.Contains(e.Match_type))  //上次赢了的类型
                //.Where(e => bjdanchang.Contains(e.Match_type)) //出错率大于50的类型
                //.Where(e=>e.Result_goals=="30") 
                // .Where(e => e.Result_goals.Length == 3)
                    .Where(e => e.bj_select == 1)
                    .OrderBy(e => e.Match_time);
            return tables.AsEnumerable();
        }
        public IEnumerable<Analysis_Review> GetPredictOne()
        {
            var ar = from p in matches.Analysis_Review.Where(p => p.Result_wdl != null).AsParallel()
                     //where p.Result_wdl.Contains("W") || p.Result_wdl.Contains("L")
                     where p.result_grnn.Contains("yes") || p.result_grnn.Contains("no")
                     where p.bj_select == 1
                     where p.result_grnn != null
                     where p.Result_wdl != null
                     select p;
            return ar.AsEnumerable();
        }
        public IEnumerable<Analysis_Review> GetPredictOne_Match(string tt)
        {
            var ar = from p in matches.Analysis_Review.Where(p => p.Result_wdl != null).AsParallel()

                     where p.result_grnn.Contains("yes") || p.result_grnn.Contains("no")

                     //where todayMatchType_two.Contains(p.Match_type)
                     where p.Match_type == tt

                     where p.bj_select == 1
                     where p.result_grnn != null
                     where p.Result_wdl != null
                     orderby p.Match_time
                     select p;
            return ar.AsEnumerable();
        }
        #region Matlab和Csharp混合编程的方法，利用Matlab运算得出想要的一系列数据 之前数据
        // 反射的经典实现，变量的反复抽象，把变化部分减少到最小，增强稳定部分，有利于扩展
        public List<MatchPoint<float>> ployfitSeries(List<MatchPoint<double>> result, int LastNowDiff)
        {
            List<MatchPoint<float>> fitseries = new List<MatchPoint<float>>();
            //在此反射数据系列，计算需要拟合的成员，由于输入和输出的数据类型不同，使用泛型<>，T
            PropertyInfo[] field = typeof(MatchPoint<>).GetProperties();
            int size = result.Count();
            var fisfilter = field.Where(e => e.Name == "LastMatchWDL" || e.Name == "LastMatchGoals" || e.Name == "LastMatchOddEven");
            foreach (PropertyInfo fi in fisfilter)
            {
                double[] Y = new double[size];
                double[] X = new double[size];
                double[] X1 = new double[size];
                for (int i = 0; i < size; i++)
                {
                    //在此指定<>类型是整数
                    PropertyInfo fiIn = typeof(MatchPoint<double>).GetProperty(fi.Name);
                    //反射获取值
                    Y[i] = Convert.ToDouble(fiIn.GetValue(result[i], null));
                    X[i] = Convert.ToDouble(result[i].LastMatchOverTime);
                    if (i != size - 1)
                        X1[i] = Convert.ToDouble(result[i + 1].LastMatchOverTime);
                    else
                        X1[i] = Convert.ToDouble(LastNowDiff);
                    MatchPoint<float> f = new MatchPoint<float>();
                    f.LastMatchOverTime = (float)X1[i];
                    if (fitseries.Count == i) fitseries.Add(f);  //如果累加就不行，这种方式，最大值不超过i
                }
                myCurveFitclass mmm = new myCurveFitclass(X, Y);
                mmm.CurvefitValue(LastNowDiff);
                //在此指定<>类型是小数
                PropertyInfo fiOut = typeof(MatchPoint<float>).GetProperty(fi.Name); //这里改属性
                //反射设定值 
                for (int j = 0; j < mmm.PredictionsNew.Length; j++) { fiOut.SetValue(fitseries[j], (float)mmm.PredictionsNew[j], null); }
            }
            return fitseries;
        }
        #endregion

    }
    public partial class Form1 : Form
    {

        //过滤 filter,让球

        //让球，1
        //测试函数的正确运行
        //2012.7.28

        private void testRunMatchTypeRate(string tt)
        {
            PredictAnalysisAfter paa = new PredictAnalysisAfter();
            double y = 0;
            //using (DataClassesMatchDataContext2 matches = new DataClassesMatchDataContext2(Conn.conn))
            //{
            //var ar = from p in matches.Analysis_Review.Where(p => p.Result_wdl != null).AsParallel()

            //         where p.result_grnn.Contains("yes") || p.result_grnn.Contains("no")

            //         //where todayMatchType_two.Contains(p.Match_type)
            //         where p.Match_type == tt

            //         where p.bj_select == 1
            //         where p.result_grnn != null
            //         where p.Result_wdl != null
            var ar = from p in paa.GetPredictOne_Match(tt)
                     group p by new { Match_time = p.Match_time.Value.Date, p.Match_type } into ttt
                     select new
                     {
                         ddate = ttt.Key.Match_time,
                         ttype = ttt.Key.Match_type,
                         wdlsuccrate = 100.0 * ttt.Where(e => e.result_grnn.Contains("yes")).Count() / ttt.Count(),
                         //wdlsuccrate = 100 * ttt.Where(e => e.result_grnn.Contains("yes")).Count() / ttt.Count(),
                     };
            //var tables = from p in matches.Analysis_Review.Where(p => p.Result_wdl != null).AsParallel()
            //             where p.result_grnn.Contains("yes") || p.result_grnn.Contains("no")

            //             //where todayMatchType_two.Contains(p.Match_type)
            //             where p.Match_type == tt

            //             where p.bj_select == 1
            //             where p.result_grnn != null
            //             where p.Result_wdl != null
            //             orderby p.Match_time
            var tables = from p in paa.GetPredictOne_Match(tt)
                         select p;

            gridControl1.DataSource = tables.ToList();
            button7.PerformClick();

            List<MatchPoint<double>> CurveFit = new List<MatchPoint<double>>();
            var ar_order = ar.Where(e => e.ttype == tt).OrderBy(e => e.ddate);
            var xmin = ar.Min(e => e.ddate);
            var xd = (DateTime.Now.Date - xmin).Days;
            foreach (var item in ar_order)
            {
                MatchPoint<double> m = new MatchPoint<double>();
                m.LastMatchWDL = item.wdlsuccrate;
                m.matchTime = item.ddate;
                m.LastMatchOverTime = (item.ddate - xmin).Days;
                CurveFit.Add(m);
            }
            if (CurveFit.Count > 5)
            {
                var ylist = paa.ployfitSeries(CurveFit, xd);//这里做预测

                y = ylist.OrderByDescending(e => e.LastMatchOverTime)
                   .Select(e => e.LastMatchWDL).First();

            }


            chartControl1.Series.Clear();
            Series series1 = new Series("testRunMatchTypeRate", ViewType.Bar);
            foreach (var m in CurveFit)
                series1.Points.Add(new SeriesPoint(m.LastMatchOverTime, m.LastMatchWDL));
            series1.Points.Add(new SeriesPoint(xd, y));
            chartControl1.Series.Add(series1);
            series1.Label.Visible = true;

            XYDiagram diagram = (XYDiagram)chartControl1.Diagram;
            diagram.AxisY.LogarithmicBase = 2;
            diagram.AxisY.Logarithmic = true;
            //}
        }

        private void RunMatchTypeRate()
        {
            PredictAnalysisAfter paa = new PredictAnalysisAfter();
            matchtype_rate = new Dictionary<string, double>();
            //using (DataClassesMatchDataContext2 matches = new DataClassesMatchDataContext2(Conn.conn))
            //{
            //var ar = from p in matches.Analysis_Review.Where(p => p.Result_wdl != null).AsParallel()
            //         //where p.Result_wdl.Contains("W") || p.Result_wdl.Contains("L")
            //         where p.result_grnn.Contains("yes") || p.result_grnn.Contains("no")
            //         where p.bj_select == 1
            //         where p.result_grnn != null
            //         where p.Result_wdl != null
            var ar = from p in paa.GetPredictOne()
                     group p by new { p.Match_time.Value.Date, p.Match_type } into ttt
                     select new
                     {
                         ddate = ttt.Key.Date,
                         ttype = ttt.Key.Match_type,
                         //ttt,
                         grnnfail = ttt.Where(e => e.result_grnn.Contains("yes")).Count(),
                         grnnsucc = ttt.Where(e => e.result_grnn.Contains("no")).Count(),
                         cnt = ttt.Count(),
                         //grnnfailrate = 100 * ttt.Where(e => e.result_grnn.Contains("no")).Count() / ttt.Count(),

                         //wdlfail = ttt.Where(e => e.Result_wdl.Contains("W")).Count(),
                         //wdlsucc = ttt.Where(e => e.Result_wdl.Contains("L")).Count(),
                         grnnsuccrate = 100.0 * ttt.Where(e => e.result_grnn.Contains("yes")).Count() / ttt.Count(),
                     };

            //var artype = matches.Analysis_Review.AsParallel()
            //    //.Where(e => e.result_grnn == null)
            //    //.Where(e => e.Result_wdl == null
            //    //.Where(e=>!e.Result_wdl.Contains("W") && !!e.Result_wdl.Contains("L"))
            //.Where(e => e.full_home_goals == null)
            //.Select(e => e.Match_type).Distinct();

            //filter_match = new List<string>();

            //if (todayMatchType == null) todayAnalysisReview(false);

            //todayAnalysisReview(1, false);

            foreach (var tt in paa.GetTodayMatch())
            {

                if (todayMatchType.Count > 0)
                    if (todayMatchType.Contains(tt))
                    {
                        List<MatchPoint<double>> CurveFit = new List<MatchPoint<double>>();
                        var ar_order = ar.Where(e => e.ttype == tt).OrderBy(e => e.ddate);
                        var xmin = ar.Min(e => e.ddate);
                        var xd = (DateTime.Now.Date - xmin).Days;
                        foreach (var item in ar_order)
                        {
                            MatchPoint<double> m = new MatchPoint<double>();
                            m.LastMatchWDL = item.grnnsuccrate;
                            m.matchTime = item.ddate;
                            m.LastMatchOverTime = (item.ddate - xmin).Days;
                            CurveFit.Add(m);
                        }
                        if (CurveFit.Count > 5)
                        {
                            var ylist = paa.ployfitSeries(CurveFit, xd);//这里做预测

                            var y = ylist.OrderByDescending(e => e.LastMatchOverTime)
                                .Select(e => e.LastMatchWDL).First();
                            matchtype_rate.Add(tt, y);
                        }
                    }
            }
            //}
        }

        private void btn_today_predict_Click(object sender, EventArgs ee)
        {
            //IEnumerable<Analysis_Review> tables;
            //using (DataClassesMatchDataContext2 matches = new DataClassesMatchDataContext2(Conn.conn))
            //{
            //    tables = matches.Analysis_Review
            //        .Where(e => e.Match_time.Value > DateTime.Now.AddDays(overday))
            //        //.Where(e => e.Result_goals.Length == 3)  //只有2个结果，修改成3个结果的
            //      .Where(e => e.bj_select == 1)  //非让球的
            //      .OrderBy(e => e.Match_time);
            PredictAnalysisAfter paa = new PredictAnalysisAfter();
            var tables = from p in paa.GetPredictOne_Today(overday)
                         select p;

            //todayMatchType_two = new List<string>();
            todayMatchType = tables.Select(e => e.Match_type).Distinct().ToList();

            gridControl1.DataSource = tables.ToList();
            //}


            button7.PerformClick();
        }

        private void btn_last_predict_Click(object sender, EventArgs e)
        {
            RunMatchTypeRate();
            chartControl1.Series.Clear();
            Series series1 = new Series("grnnsucc", ViewType.Bar);
            foreach (var m in matchtype_rate)
            {
                //if (m.Value > 0)
                series1.Points.Add(new SeriesPoint(m.Key, m.Value));
                if (m.Value > rate_threshold_one)
                    filter_match.Add(m.Key);
            }
            chartControl1.Series.Add(series1);
            series1.Label.Visible = true;

            XYDiagram diagram = (XYDiagram)chartControl1.Diagram;
            diagram.AxisY.LogarithmicBase = 2;
            diagram.AxisY.Logarithmic = true;
        }

        private void btn_filter_predict_Click(object sender, EventArgs ee)
        {
            this.listView2.View = View.Details;
            listView2.Items.Clear();
            foreach (string m in filter_match)
                listView2.Items.Add(m);

            //todayAnalysisReview(1, true);

            //gridControl1.DataSource = todayMatchType;

            //DataClassesMatchDataContext2 matches = new DataClassesMatchDataContext2(Conn.conn);
            //var tables = matches.Analysis_Review
            //                   .Where(e => e.Match_time.Value > DateTime.Now.AddDays(overday))
            //                    .Where(e => filter_match.Contains(e.Match_type))  //上次赢了的类型
            //    //.Where(e => bjdanchang.Contains(e.Match_type)) //出错率大于50的类型
            //    //.Where(e=>e.Result_goals=="30") 
            //    // .Where(e => e.Result_goals.Length == 3)
            //                   .Where(e => e.bj_select == 1)
            //                   .OrderBy(e => e.Match_time);
            PredictAnalysisAfter paa = new PredictAnalysisAfter();
            var tables = from p in paa.GetPredictOne_TodayFilter(overday, filter_match)
                         select p;

            //todayMatchType = new List<string>();
            //todayMatchType = tables.Select(e => e.Match_type).Distinct().ToList();

            gridControl1.DataSource = tables.ToList();

            //gridControl1.Refresh();
            //gridView1.PopulateColumns();

            //DevExpress.XtraGrid.Columns.GridColumn col = gridView1.Columns[19];
            //col.DisplayFormat.FormatString = "yyyy-MM-dd HH:mm:ss";
            //col.DisplayFormat.FormatType = DevExpress.Utils.FormatType.Custom;
            //gridView1.OptionsView.ColumnAutoWidth = false;
            //gridView1.BestFitColumns();


            //if (filter)
            //{

            button7.PerformClick();
            /*
            for (int i = 0; i < 10; i++) gridView1.Columns[i].Visible = false;
            for (int i = 11; i < 18; i++) gridView1.Columns[i].Visible = false;
            for (int i = 23; i < 28; i++) gridView1.Columns[i].Visible = false;
             * */
            //}

            //设置并制作Foot下面的统计信息
            //gridView1.Columns[19].SummaryItem.DisplayFormat = "{0}";
            ////gridView1.Columns[0].SummaryItem.FieldName = "analysis_review_id";
            //gridView1.Columns[19].SummaryItem.SummaryType = DevExpress.Data.SummaryItemType.Count;
        }

        private void btn_send_predict_Click(object sender, EventArgs e)
        {
            /*
if (SendPredictEmail.SendEmail("hongpingwei@sina.com", "hp",
     "13533233161@139.com", "hp",
     DateTime.Now.ToLongDateString(), get_today_predict(), false, null,
     "smtp.sina.com", "hongpingwei", "nokia"))
    MessageBox.Show("Email sent successfully");
else
    MessageBox.Show("Failed to send email");
 * */

            if (SendPredictEmail.SendEmail("jc777777@163.com", "jc777",
                 "jc777777@163.com", "jc777",
                 DateTime.Now.ToLongDateString(), get_today_predict(), false, null,
                 "smtp.163.com", "jc777777", "123qweasd"))
                //MessageBox.Show("Email sent successfully");
                toolStripStatusLabel1.Text = "Email sent successfully";
            else
                //MessageBox.Show("Failed to send email");
                toolStripStatusLabel1.Text = "Failed to send email";
        }
    }
}